﻿#include "drv_key.h"
#include "drv_led.h"
#include "drv_ts.h"
#include "ak_thread.h"
#include "drv_pwm.h"

// threads
ak_pthread_t led_handle;
ak_pthread_t key_handle;
ak_pthread_t ts_handle;
static void* led_func(void* param);
static void* key_func(void* param);
static void* ts_func(void* param);

// sem
ak_sem_t led_ctrl_sem;

// locker
ak_rwlock_t led_locker;
ak_rwlockattr_t led_locker_attr;

// value
int led_level = 0;

static inline void usage(const char *app)
{
	ak_print_normal("Usage: %s [options]\n\n"
		"options:\n"
		" 1   touch test\n"
		"-h   help\n",app);	
}

void writeLedLevel(int value){
    ak_thread_rwlock_wrlock(&led_locker);
    led_level = value;
    ak_thread_rwlock_unlock(&led_locker);

    // post sem
    ak_thread_sem_post(&led_ctrl_sem);    
}

int readLedLevel(void){
    int value;
    ak_thread_rwlock_rdlock(&led_locker);
    value = led_level;
    ak_thread_rwlock_unlock(&led_locker);
    return value;
}

int initDevices(void){
    int res = -1;
    
    // init key
    res = ak_drv_key_open();
    if(res){
  	  printf( "ak_drv_key_open fail.\n");
	  return 1;
  	}

    // init ts
    res = ak_drv_ts_open();
    if(res)
	{
		printf( "ak_drv_ts_open fail.\n");
		return -1;
  	}

    // init pwm
    res = drv_pwm_init();
    if(res)
	{
		printf( "pwm_open fail.\n");
		return -1;
  	}
}

int initThreads(void){
    // init sem
    ak_thread_sem_init(&led_ctrl_sem, 0);

    // init locker
    ak_thread_rwlock_init(&led_locker, &led_locker_attr);

    // create thread
    ak_thread_create(&led_handle, led_func, NULL, ANYKA_THREAD_MIN_STACK_SIZE, 11);
    ak_thread_create(&key_handle, key_func, NULL, ANYKA_THREAD_MIN_STACK_SIZE, 11);
    // ak_thread_create(&ts_handle, ts_func, NULL, ANYKA_THREAD_MIN_STACK_SIZE, 11);

    // start threads
    ak_thread_join(led_handle);
    ak_thread_join(key_handle);
    // ak_thread_join(ts_handle);
}


void* led_func(void* param){ 
    int led;
    while(1){
        // wait for sem
        ak_thread_sem_wait(&led_ctrl_sem);

        // control func
        led = readLedLevel();
        ak_print_normal("set led level %d\n", led);	
        ak_drv_led_set("state_led", led? 1 : 0);
    }
    ak_thread_exit();
}

void* key_func(void* param){
    struct key_event key;
    memset(&key,0,sizeof(key));
    int res;
    int temp;
    while(1){
        memset(&key,0,sizeof(key));
        res = ak_drv_key_get_event(&key,1000);

        // available key value
        if(!res){
            switch (key.code)
            {
                case 103:   
                case 108:   
                case 102: 
                    // writeLedLevel(0);	

                    res = read_cycle_percent();
                    temp = res + 10;
                    if(temp > 100)
                        temp = 100;
                    set_pwm_percent(temp);
                    ak_print_normal("set brightnes %d\n", temp);
                    break;  
                case 105:   
                case 106:   
                case 28: 
                    // writeLedLevel(1);

                    res = read_cycle_percent();
                    temp = res - 10;
                    if(temp < 0)
                        temp = 0;
                    set_pwm_percent(temp);
                    ak_print_normal("set brightnes %d\n", temp);
                    break;   
                default: break;
            }
        }
    }
    ak_thread_exit();
}

void* ts_func(void* param){
    struct ak_ts_event ts;
    int res;

    while(1){
        res = ak_drv_ts_get_event(&ts, 1000);
		
		/* 
		*get ts, output 
		*/
		if(res == 0) 
		{
            if(ts.info[0].x < 500){
                ak_print_normal("write led level %d\n", 1);
                writeLedLevel(1);
            }
            else{
                ak_print_normal("write led level %d\n", 0);
                writeLedLevel(0);
            }

	   	}
    }
    ak_thread_exit();
}

int main (int argc, char **argv)
{    
    // init devices
    if(initDevices()) return -1;

    // init threads
    if(initThreads()) return -1;

    while(1);
    return 0;
}


